%include "io.inc"

section .text
global main
main:
    mov ebp, esp; 程序开始时，修改 ebp = esp，表示空栈，有利于之后的调试

    ;调用函数，通过栈传递参数
    push 10
    push 20
    call avg_fun ; call 命令会将下一条指令的地址压栈后进行跳转
    add esp, 8   ; 修改 esp，恢复空栈。也可以两次 pop，也可以 mov esp, ebp

    PRINT_DEC 4, eax
    xor eax, eax
    ret

avg_fun:
    push ebp              ; 保存 ebp，即旧的栈低指针
    mov ebp, esp          ; 新的作用域开始时使 ebp = esp，方便调试

    xor eax, eax          ; eax = 0
    add eax, [ebp + 8]    ; eax += 10。推荐使用 ebp 计算偏移量，因为它通常不会改变。使用 esp 也没有错
    add eax, [ebp + 12]   ; eax += 20
    sar eax, 1            ; 右移 1 位

    pop ebp               ; 恢复 ebp
    ret ; 此时栈顶元素记录的是要跳回的位置，执行 ret 会弹栈并跳回
